package cn.collin.commons.web.taglib;

import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import cn.collin.commons.domain.PageResult;
import cn.collin.commons.web.filter.OpenSessionInViewHibernateFilter;

/**
 * execute hql by page
 * 
 * http://collincode.googlecode.com
 * 
 * @author collin.code@gmail.com
 * 
 */
public class HQueryByPageTag extends TagSupport {

	private static final long serialVersionUID = 1L;

	String var;

	String hql;

	String countHql;

	String pageIndex;

	String pageLength;

	public void setPageIndex(String pageIndex) {
		this.pageIndex = pageIndex;
	}

	public void setPageLength(String pageLength) {
		this.pageLength = pageLength;
	}

	public void setHql(String hql) {
		this.hql = hql;
	}

	public void setVar(String var) {
		this.var = var;
	}

	@Override
	public int doStartTag() throws JspException {
		hql = (String) ExpressionUtil.evalNotNull("hpage", "hql", hql,
				String.class, this, pageContext);
		countHql = (String) ExpressionUtil.evalNotNull("hpage", "countHql",
				countHql, String.class, this, pageContext);
		pageIndex = (String) ExpressionUtil.evalNotNull("hpage", "pageIndex",
				pageIndex, String.class, this, pageContext);
		if (pageIndex == null || pageIndex.length() == 0) {
			pageIndex = "1";
		}
		return SKIP_BODY;
	}

	@Override
	public int doEndTag() throws JspException {
		Session session = (Session) TransactionSynchronizationManager
				.getResource(OpenSessionInViewHibernateFilter.SESSION_NAME);
		int _pageLength = Integer.parseInt(pageLength);
		int _pageIndex = Integer.parseInt(pageIndex);
		int firstResult = (_pageIndex - 1) * _pageLength;
		Query query = session.createQuery(hql);
		query.setFirstResult(firstResult);
		query.setMaxResults(_pageLength);
		query.setFetchSize(_pageLength);
		List results = query.list();
		int allResultsAmount = ((Long) session.createQuery(countHql).list()
				.get(0)).intValue();
		int pagesAmount = new Double(Math.ceil(new Integer(allResultsAmount)
				.doubleValue()
				/ new Integer(pageLength).doubleValue())).intValue();
		PageResult ps = new PageResult(_pageIndex, _pageLength, pagesAmount,
				allResultsAmount, results);
		pageContext.setAttribute(var, ps, PageContext.PAGE_SCOPE);
		return EVAL_PAGE;
	}

	public void setCountHql(String countHql) {
		this.countHql = countHql;
	}
}
